package rov.ui.gfx;


import java.io.IOException;
import java.io.InputStream;
import java.nio.Buffer;

import javax.media.opengl.*;
import javax.media.opengl.glu.*;


// implementation of Renderable backed by an OpenGL Vertex Buffer Object
public class VBORenderable implements Renderable {
    protected GL2 mGl;
    protected int[] mBuffers;
    protected int[] mBufferSizes;


    public VBORenderable(GL2 gl) {
        mGl = gl;
    }


    // creates the specified amount of buffers
    public boolean init(int numBuffers) {
        mBuffers = new int[numBuffers];
        mBufferSizes = new int[numBuffers];

        //mGl.glEnableClientState(mGl.GL_VERTEX_ARRAY);
        //mGl.glEnableClientState(mGl.GL_COLOR_ARRAY);


        // check version
        String versionStr = mGl.glGetString(GL.GL_VERSION);
        System.out.println("GL version:" + versionStr);
        versionStr = versionStr.substring( 0, 4);

        //float version = new Float(versionStr).floatValue();
        //boolean versionOK = (version >= 1.59f) ? true : false;
        //System.out.println("GL version:" + versionStr + "  ->" + versionOK);

        // check if buffer object extension is available.
        boolean extensionOK = mGl.isExtensionAvailable("GL_ARB_vertex_buffer_object");
        System.out.println("VBO extension: " + extensionOK);

        // check for buffer object functions
        boolean functionsOK = 
          mGl.isFunctionAvailable("glGenBuffersARB") &&
          mGl.isFunctionAvailable("glBindBufferARB") &&
          mGl.isFunctionAvailable("glBufferDataARB") &&
          mGl.isFunctionAvailable("glDeleteBuffersARB");      
        System.out.println("Functions: " + functionsOK);

        if(!extensionOK || !functionsOK) {
            System.err.println("VBOs not supported.");
            return false;
        }

        // create buffers
        mGl.glGenBuffers(numBuffers, mBuffers, 0);

        //for (int i = 0; i < numBuffers; i++) {
        //    mGl.glBindBuffer(GL.GL_ARRAY_BUFFER, mBuffers[i]);
        //}

//mGl.glBindBuffer(GL.GL_ARRAY_BUFFER, mBuffers[0]);
//mGl.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, mBuffers[1]);

        return true;
    }


    /*
	copies data.limit() bytes starting at position 0
        from data into an OpenGL buffer object

	usage can be one of the following:
		GL.GL_STATIC_DRAW
		GL.GL_STATIC_READ
		GL.GL_STATIC_COPY
		GL.GL_DYNAMIC_DRAW
		GL.GL_DYNAMIC_READ
		GL.GL_DYNAMIC_COPY

	apparently these don't exist (dumb):
		GL.GL_STREAM_DRAW
		GL.GL_STREAM_READ
		GL.GL_STREAM_COPY
    */
    public void setBufferContents(int bufferIndex, Buffer data, int usage) {
        data.position(0);
        mBufferSizes[bufferIndex] = data.limit() * 4;

System.out.println("setBufferContents for buffer: " + bufferIndex + ", size: " + data.limit());

        if (bufferIndex == 0) {
            mGl.glBindBuffer(GL.GL_ARRAY_BUFFER, mBuffers[bufferIndex]);
            mGl.glBufferData(GL.GL_ARRAY_BUFFER, mBufferSizes[bufferIndex], data, usage);
            mGl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0);
        } else {
            mGl.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, mBuffers[bufferIndex]);
            mGl.glBufferData(GL.GL_ELEMENT_ARRAY_BUFFER, mBufferSizes[bufferIndex], data, usage);
            mGl.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, 0);
        }
    }


    public void render() {
mGl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL2.GL_LINE);

            // Enable Pointers
           // mGl.glEnableClientState(GL2.GL_VERTEX_ARRAY);  // Enable Vertex Arrays
            // Enable Texture Coord Arrays
            //gl.glEnableClientState(GL.GL_TEXTURE_COORD_ARRAY);  

            // Set Pointers To Our Data
            //if (fUseVBO) {
                //gl.glBindBufferARB(GL.GL_ARRAY_BUFFER, mesh.VBOTexCoords[0]);
                // Set The TexCoord Pointer To The TexCoord Buffer
                //gl.glTexCoordPointer(2, GL.GL_FLOAT, 0, 0);    
                mGl.glBindBuffer(GL.GL_ARRAY_BUFFER, mBuffers[0]);
                // Set The Vertex Pointer To The Vertex Buffer
            //    mGl.glVertexPointer(3, GL.GL_FLOAT, 0, 0);    


                mGl.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, mBuffers[1]);
                //mGl.glVertexPointer(3, GL.GL_FLOAT, 0, 0);

            mGl.glEnableClientState(GL2.GL_VERTEX_ARRAY);  // Enable Vertex Arrays
            mGl.glVertexPointer(3, GL.GL_FLOAT, 0, 0);    

mGl.glDrawElements(GL.GL_TRIANGLES, mBufferSizes[1]/4, GL.GL_UNSIGNED_INT, 0);

            //} else {
                // Set The Vertex Pointer To Our Vertex Data
                //gl.glVertexPointer(3, GL.GL_FLOAT, 0, mesh.vertices); 
                // Set The Vertex Pointer To Our TexCoord Data
                //gl.glTexCoordPointer(2, GL.GL_FLOAT, 0, mesh.texCoords); 
            //}

            // Render
            // Draw All Of The Triangles At Once
            //mGl.glDrawArrays(GL.GL_TRIANGLES, 0, mBufferSizes[1]);  

            mGl.glDisableClientState(GL2.GL_VERTEX_ARRAY);

                mGl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0);
                mGl.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, 0);

            // Disable Pointers
            // Disable Vertex Arrays
            // Disable Texture Coord Arrays
            //gl.glDisableClientState(GL.GL_TEXTURE_COORD_ARRAY);      
    }
}
